﻿///////////////////////////////////////////////////////////////////////////
// 文件名:     progressmanage.cpp
// 描述:
// 作者:      颜磊
// 创建时间:   2024-06-08 23:46
///////////////////////////////////////////////////////////////////////////
#include "progressmanage.h"
#include "QDebug"
#include "comutil.h"

#include "WtsApi32.h"
#include "comutil.h"
#include "tchar.h"
#pragma comment(lib, "comsuppw.lib")
#include <QDebug>

ProgressManage::ProgressManage()
{
    //    processor_count = -1;
    //    last_time = 0;
    //    last_system_time = 0;
}

void wchar_to_string(string &szDst, wchar_t *wchar)
{
    //    wchar_t * wText = wchar;
    //    DWORD dwNum = WideCharToMultiByte(CP_ACP,NULL,wText,-1,NULL,0,NULL,FALSE);// WideCharToMultiByte的运用
    //    char *psText; // psText为char*的临时数组，作为赋值给std::string的中间变量
    //    psText = new char[dwNum];
    //    WideCharToMultiByte (CP_ACP,NULL,wText,-1,psText,dwNum,NULL,FALSE);// WideCharToMultiByte的再次运用
    //    szDst = psText;// std::string赋值
    //    delete []psText;// psText的清除

    //第一次调用确认转换后单字节字符串的长度，用于开辟空间
    int pSize = WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), NULL, 0, NULL, NULL);
    char *pCStrKey = new char[pSize + 1];
    //第二次调用将双字节字符串转换成单字节字符串
    WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), pCStrKey, pSize, NULL, NULL);
    pCStrKey[pSize] = '\0';
    szDst = pCStrKey;
    delete[] pCStrKey; // 释放动态分配的内存
}

LPCWSTR string_to_wchar(string str)
{
    //string 转 char*
    char *pCStrKey = (char *)str.c_str();
    //第一次调用返回转换后的字符串长度，用于确认为wchar_t*开辟多大的内存空间
    int pSize = MultiByteToWideChar(CP_ACP, 0, pCStrKey, strlen(pCStrKey) + 1, NULL, 0);
    wchar_t *pWCStrKey = new wchar_t[pSize];
    //第二次调用将单字节字符串转换成双字节字符串
    MultiByteToWideChar(CP_ACP, 0, pCStrKey, strlen(pCStrKey) + 1, pWCStrKey, pSize);
    return pWCStrKey;
}

LPCWSTR string2LPCWSTR(string str)
{
    //第一次调用返回转换后的字符串长度，用于确认为wchar_t*开辟多大的内存空间
    int len = MultiByteToWideChar(CP_OEMCP, 0, str.c_str(), -1, NULL, 0);
    wchar_t *buffer = new wchar_t[len + 1];
    memset(buffer, 0, (len + 1) * sizeof(wchar_t));
    //第二次调用将单字节字符串转换成双字节字符串
    MultiByteToWideChar(CP_OEMCP, 0, str.c_str(), str.length(), (LPWSTR)buffer, len);
    return buffer;
}

wstring string_to_wstring(string str)
{
    wstring result;
    int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size(), NULL, 0);
    wchar_t *buffer = new wchar_t[len + 1];
    memset(buffer, 0, (len + 1) * sizeof(wchar_t));
    MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.size(), buffer, len);
    result.append(buffer);
    delete[] buffer;
    return result;
}

string wstring_to_string(wstring wstr)
{
    string result;
    int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
    char *buffer = new char[len + 1];
    memset(buffer, 0, (len + 1) * sizeof(char));
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
    result.append(buffer);
    delete[] buffer;
    return result;
}

string ws2s(const wstring &ws)
{
    _bstr_t t = ws.c_str();
    char *pchar = (char *)t;
    string result = pchar;
    return result;
}

wstring s2ws(const string &s)
{
    _bstr_t t = s.c_str();
    wchar_t *pchar = (wchar_t *)t;
    wstring result = pchar;
    return result;
}

string TCHAR2STRING(TCHAR *str)
{
    std::string strstr;
    int iLen = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
    char *chRtn = new char[iLen * sizeof(char)];
    WideCharToMultiByte(CP_UTF8, 0, str, -1, chRtn, iLen, NULL, NULL);
    strstr = chRtn;
    delete[] chRtn; // 释放动态分配的内存
    return strstr;
}

// 辅助函数：宽字符转UTF-8
std::string WcharToString(const WCHAR *wstr)
{
    int len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
    if (len <= 0)
        return "";
    std::string result(len - 1, '\0');
    WideCharToMultiByte(CP_UTF8, 0, wstr, -1, &result[0], len, NULL, NULL);
    return result;
}

/// 时间转换
static uint64_t convert_time_format(const FILETIME *ftime)
{
    LARGE_INTEGER li;

    li.LowPart = ftime->dwLowDateTime;
    li.HighPart = ftime->dwHighDateTime;
    return li.QuadPart;
}

/// 获得CPU的核数
static int get_processor_number()
{
    SYSTEM_INFO info;
    GetSystemInfo(&info);
    return (int)info.dwNumberOfProcessors;
}

bool ProgressManage::checkProcessByName(string &strExe)
{
    bool bResult = false;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (INVALID_HANDLE_VALUE == hSnapshot)
    {
        return NULL;
    }
    PROCESSENTRY32 pe = {sizeof(pe)};
    for (BOOL ret = Process32First(hSnapshot, &pe); ret; ret = Process32Next(hSnapshot, &pe))
    {
        wchar_t *process_str = pe.szExeFile;
        string current_process_name;
        wchar_to_string(current_process_name, process_str);
        if (current_process_name == strExe)
        {
            qInfo() << "check process";
            bResult = true;
            break;
        }
    }
    CloseHandle(hSnapshot);
    return bResult;
}

bool ProgressManage::checkProcessById(DWORD &processId)
{
    bool res = false;
    // 进程ID有效（非零）
    if (0 != processId)
    {
        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processId);
        if (NULL == hProcess)
        {
            qInfo() << __FUNCTION__ << "OpenProcess fail" << GetLastError();
        }
        else
        {
            DWORD dwExitCode = 0;
            BOOL bGet = GetExitCodeProcess(hProcess, &dwExitCode);
            if (bGet && (STILL_ACTIVE == dwExitCode)) // 正在运行
            {
                qInfo() << "check process";
                res = true;
            }
            else
            {
                qInfo() << "exit ProcessID:" << processId << "flag:" << bGet << "code:" << dwExitCode;
            }

            CloseHandle(hProcess);
            hProcess = NULL;
        }
    }
    else
    {
        qInfo() << "exit ProcessID invalid";
    }
    return res;
}

bool ProgressManage::getProcessIdByName(string &strExe, DWORD &processId)
{
    bool res = false;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (INVALID_HANDLE_VALUE == hSnapshot)
    {
        qCritical() << __FUNCTION__ << "CreateToolhelp32Snapshot error ";
        return res;
    }
    PROCESSENTRY32 pe = {sizeof(pe)};
    for (BOOL ret = Process32First(hSnapshot, &pe); ret; ret = Process32Next(hSnapshot, &pe))
    {
        if (strcmp(_bstr_t(pe.szExeFile), strExe.c_str()) == 0)
        {
            processId = pe.th32ProcessID;
            res = true;
            break;
        }
    }
    CloseHandle(hSnapshot);
    return res;
}

bool ProgressManage::getWinlogonProcessId(DWORD &processId)
{
    processId = 0;
    DWORD consoleSessionId = WTSGetActiveConsoleSessionId();
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE)
    {
        qCritical("%s: CreateToolhelp32Snapshot failed (Error: %lu)",
                  __FUNCTION__, GetLastError());
        return false;
    }

    PROCESSENTRY32 pe = {sizeof(PROCESSENTRY32)};
    for (BOOL ret = Process32First(hSnapshot, &pe); ret; ret = Process32Next(hSnapshot, &pe))
    {
        if (_wcsicmp(pe.szExeFile, L"winlogon.exe") == 0)
        {
            DWORD sessionId = 0;
            if (ProcessIdToSessionId(pe.th32ProcessID, &sessionId))
            {
                // 优先返回控制台会话的winlogon
                if (sessionId == consoleSessionId)
                {
                    processId = pe.th32ProcessID;
                    CloseHandle(hSnapshot);
                    return true;
                }
                // 记录第一个找到的winlogon作为备选
                if (processId == 0)
                {
                    processId = pe.th32ProcessID;
                }
            }
        }
    }

    CloseHandle(hSnapshot);
    return processId != 0;
}

BOOL DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
{

    TCHAR szDriveStrings[MAX_PATH] = {0};
    TCHAR szDosBuf[MAX_PATH] = {0};
    TCHAR szResultBuf[MAX_PATH] = {0};
    LPTSTR pDriveStr = NULL;

    // 获取盘符名到缓冲
    if (::GetLogicalDriveStrings(_countof(szDriveStrings), szDriveStrings))
    {
        // 遍历盘符名
        for (int i = 0; i < _countof(szDriveStrings); i += 4)
        {
            pDriveStr = &szDriveStrings[i];
            pDriveStr[2] = _T('\0');

            // 查询盘符对应的DOS设备名称
            if (!::QueryDosDevice(pDriveStr, szDosBuf, _countof(szDosBuf)))
            {
                break;
            }

            // 对比路径前缀
            size_t nLen = _tcslen(szDosBuf);
            if (0 == _tcsnicmp(pszDosPath, szDosBuf, nLen))
            {
                lstrcpy(pszNtPath, pDriveStr);
                lstrcat(pszNtPath, pszDosPath + nLen);
                return TRUE;
            }
        }
    }

    return FALSE;
}

/**
 * @brief enableDebugPriv 提升权限函数
 */
bool ProgressManage::enableDebugPriv()
{
    HANDLE hToken = NULL;

    // 1. 打开进程令牌（最小权限原则）
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        qCritical("%s: OpenProcessToken failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }
    HandleGuard tokenGuard(hToken);

    // 2. 查找特权值
    LUID luid;
    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
    {
        qCritical("%s: LookupPrivilegeValue failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }

    // 3. 设置特权属性
    TOKEN_PRIVILEGES tkp = {
        1, // PrivilegeCount
        {  // Privileges
         {luid, SE_PRIVILEGE_ENABLED}}};

    // 4. 调整令牌特权
    if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
    {
        qCritical("%s: AdjustTokenPrivileges failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }

    // 5. 检查特权是否真正生效
    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
    {
        qCritical("%s: Privilege not assigned (Require admin rights)", __FUNCTION__);
        return false;
    }

    return true;
}

// 获取进程全路径
bool ProgressManage::GetProcessFullPath(DWORD dwPID, std::string &fullPath)
{

    // 1. 获取进程句柄（最小权限原则）
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwPID);
    if (!hProcess)
    {
        qCritical("%s: OpenProcess failed for PID %lu (Error: %lu)", __FUNCTION__, dwPID, GetLastError());
        return false;
    }
    // 2. 使用智能指针管理句柄
    HandleGuard hProcessGuard(hProcess);

    // 3. 获取设备路径
    WCHAR szImagePath[MAX_PATH] = {0};
    if (!GetProcessImageFileNameW(hProcess, szImagePath, MAX_PATH))
    {
        qCritical("%s: GetProcessImageFileName failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }

    // 4. 路径转换
    WCHAR pszFullPath[MAX_PATH] = {0};
    if (!DosPathToNtPath(szImagePath, pszFullPath))
    {
        qCritical("%s: DosPathToNtPath failed for path: %ls", __FUNCTION__, szImagePath);
        return false;
    }

    // 5. 转换为标准字符串
    fullPath = WcharToString(pszFullPath);
    return true;
}

bool ProgressManage::getProcessIdByPath(string &proPath, DWORD &processId)
{
    // 提取文件名（兼容无斜杠情况）
    const size_t lastSlashPos = proPath.find_last_of('/');
    const std::string filename = (lastSlashPos == std::string::npos) ? proPath : proPath.substr(lastSlashPos + 1);

    // 转换为宽字符比较
    std::wstring wfilename(filename.begin(), filename.end());

    // 获取进程快照（使用RAII）
    HandleGuard snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
    if (!snapshot)
    {
        qCritical("CreateToolhelp32Snapshot failed");
        return false;
    }

    PROCESSENTRY32 pe = {sizeof(PROCESSENTRY32)};
    for (BOOL ret = Process32First(snapshot, &pe); ret;
         ret = Process32Next(snapshot, &pe))
    {
        if (wcscmp(pe.szExeFile, wfilename.c_str()) == 0)
        {
            std::string processPath;
            if (GetProcessFullPath(pe.th32ProcessID, processPath))
            {
                std::replace(processPath.begin(), processPath.end(), '\\', '/');
                if (proPath == processPath)
                {
                    processId = pe.th32ProcessID;
                    return true;
                }
            }
        }
    }
    return false;
}

list<DWORD> ProgressManage::getProcessIdsByPath(string &proPath)
{
    std::list<DWORD> pIds;

    // 1. 提取文件名（兼容无斜杠情况）
    const size_t lastSlashPos = proPath.find_last_of('/');
    const std::string filename = (lastSlashPos == std::string::npos) ? proPath : proPath.substr(lastSlashPos + 1);

    // 转换为宽字符用于比较（Windows API使用宽字符）
    const std::wstring wfilename(filename.begin(), filename.end());

    // 2. 获取进程快照（使用RAII管理资源）
    HandleGuard snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
    if (!snapshot)
    {
        qCritical("%s: CreateToolhelp32Snapshot failed with error %lu", __FUNCTION__, GetLastError());
        return pIds;
    }

    // 3. 遍历进程列表
    PROCESSENTRY32 pe = {sizeof(PROCESSENTRY32)};
    for (BOOL ret = Process32First(snapshot, &pe); ret;
         ret = Process32Next(snapshot, &pe))
    {
        // 4. 比较文件名（使用宽字符比较）
        if (wcscmp(pe.szExeFile, wfilename.c_str()) != 0)
        {
            continue;
        }

        // 5. 获取并比较完整路径
        std::string processPath;
        if (!GetProcessFullPath(pe.th32ProcessID, processPath))
        {
            continue;
        }

        std::replace(processPath.begin(), processPath.end(), '\\', '/');

        if (proPath == processPath)
        {
            pIds.push_back(pe.th32ProcessID);
        }
    }
    return pIds;
}

std::string wstringToString(const wchar_t *wstr)
{
    int size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
    std::string str(size, 0);
    WideCharToMultiByte(CP_UTF8, 0, wstr, -1, &str[0], size, NULL, NULL);
    return str;
}

string ProgressManage::getProcessNameById(DWORD &processId)
{
    HandleGuard snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
    if (!snapshot)
        return "";

    PROCESSENTRY32 pe = {sizeof(PROCESSENTRY32)};
    for (BOOL ret = Process32First(snapshot, &pe); ret;
         ret = Process32Next(snapshot, &pe))
    {
        if (pe.th32ProcessID == processId)
        {
            return wstringToString(pe.szExeFile);
        }
    }
    return "";
}

int64_t systemtime_to_time_t(const SYSTEMTIME &st)
{
    tm localTm = {
        static_cast<int>(st.wSecond),
        static_cast<int>(st.wMinute),
        static_cast<int>(st.wHour),
        static_cast<int>(st.wDay),
        static_cast<int>(st.wMonth - 1),
        static_cast<int>(st.wYear - 1900),
        static_cast<int>(st.wDayOfWeek),
        0, 0};
    return static_cast<int64_t>(mktime(&localTm));
}

SYSTEMTIME time_t_to_systemtime(time_t t)
{
    tm temptm = {};
    localtime_s(&temptm, &t);
    return {
        static_cast<WORD>(1900 + temptm.tm_year),
        static_cast<WORD>(1 + temptm.tm_mon),
        static_cast<WORD>(temptm.tm_wday),
        static_cast<WORD>(temptm.tm_mday),
        static_cast<WORD>(temptm.tm_hour),
        static_cast<WORD>(temptm.tm_min),
        static_cast<WORD>(temptm.tm_sec),
        0};
}

bool ProgressManage::getProcessTimeById(DWORD &processId, uint64_t &time)
{
    HandleGuard hProcess(OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId));

    if (!hProcess)
    {
        qCritical("%s: OpenProcess failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }

    FILETIME creationTime, exitTime, kernelTime, userTime;
    if (!GetProcessTimes(hProcess, &creationTime, &exitTime, &kernelTime, &userTime))
    {
        qCritical("%s: GetProcessTimes failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }

    // 转换为本地文件时间
    FILETIME localFileTime;
    if (!FileTimeToLocalFileTime(&creationTime, &localFileTime))
    {
        qCritical("%s: FileTimeToLocalFileTime failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }

    // 转换为系统时间
    SYSTEMTIME localSystemTime;
    if (!FileTimeToSystemTime(&localFileTime, &localSystemTime))
    {
        qCritical("%s: FileTimeToSystemTime failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }

    // 获取当前时间
    SYSTEMTIME nowLocalSystemTime;
    GetLocalTime(&nowLocalSystemTime);

    // 计算时间差（秒）
    time = systemtime_to_time_t(nowLocalSystemTime) - systemtime_to_time_t(localSystemTime);

    return true;
}

void ProgressManage::killProcessById(DWORD &processId)
{
    // 1. 优先使用TerminateProcess API
    HandleGuard hProcess(OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION, FALSE, processId));
    // 2. 使用RAII管理句柄
    if (!hProcess)
    {
        qCritical("%s: OpenProcess failed (Error: %lu)", __FUNCTION__, GetLastError());
        return;
    }
    // 3. 尝试直接终止进程
    if (TerminateProcess(hProcess, 0))
        return;
    // 4. 处理特殊错误情况
    const DWORD lastError = GetLastError();
    if (lastError == ERROR_ACCESS_DENIED)
    {
        qWarning("%s: Access denied, trying elevated method (PID: %lu)",
                 __FUNCTION__, processId);
    }
    else
    {
        qCritical("%s: TerminateProcess failed (Error: %lu)",
                  __FUNCTION__, lastError);
    }
    // 5. 备用方案：使用taskkill命令
    std::string cmd = "taskkill /f /t /pid " + std::to_string(processId);
    int ret = system(cmd.c_str());

    if (ret != 0)
    {
        qCritical("%s: taskkill failed (Exit code: %d)", __FUNCTION__, ret);
    }
}

bool ProgressManage::get_cpu_usage(DWORD &processId, float &cpu_usage)
{
    // 1. 参数校验
    if (processId == 0)
    {
        qCritical("%s: Invalid process ID", __FUNCTION__);
        return false;
    }

    // 2. 使用RAII管理进程句柄
    HandleGuard hProcess(
        OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId));

    if (!hProcess)
    {
        qCritical("%s: OpenProcess failed (Error: %lu)",
                  __FUNCTION__, GetLastError());
        return false;
    }

    // 3. 获取进程时间信息
    FILETIME creationTime, exitTime, kernelTime, userTime, now;
    GetSystemTimeAsFileTime(&now);

    if (!GetProcessTimes(hProcess, &creationTime, &exitTime, &kernelTime, &userTime))
    {
        qCritical("%s: GetProcessTimes failed (Error: %lu)",
                  __FUNCTION__, GetLastError());
        return false;
    }

    // 4. 转换时间格式
    auto convertFileTime = [](const FILETIME *ft) {
        ULARGE_INTEGER uli;
        uli.LowPart = ft->dwLowDateTime;
        uli.HighPart = ft->dwHighDateTime;
        return uli.QuadPart;
    };

    const int64_t systemTime = convertFileTime(&kernelTime) + convertFileTime(&userTime);
    const int64_t currentTime = convertFileTime(&now);

    // 5. 初始化或更新进程时间数据
    auto &timeData = processTimeMap[processId];
    const auto nowClock = std::chrono::steady_clock::now();

    // 6. 首次调用处理
    if (timeData.last_system_time == 0 || timeData.last_time == 0)
    {
        timeData.last_system_time = systemTime;
        timeData.last_time = currentTime;
        timeData.last_update = nowClock;
        return false;
    }

    // 7. 计算时间差和CPU使用率
    const int64_t systemDelta = systemTime - timeData.last_system_time;
    const int64_t timeDelta = currentTime - timeData.last_time;
    const auto timePassed = std::chrono::duration_cast<std::chrono::milliseconds>(
                                nowClock - timeData.last_update)
                                .count();

    // 8. 更新最后记录的时间
    timeData.last_system_time = systemTime;
    timeData.last_time = currentTime;
    timeData.last_update = nowClock;

    // 9. 计算CPU使用率（考虑多核处理器）
    if (timeDelta > 0 && timePassed > 0)
    {
        //        SYSTEM_INFO sysInfo;
        //        GetSystemInfo(&sysInfo);
        //        const int cpuCount = sysInfo.dwNumberOfProcessors;

        //        // 转换为百分比并考虑多核
        cpu_usage = (systemDelta * 100.0f) / (timeDelta);
        return true;
    }

    return false;
}

bool ProgressManage::get_cpu_usage_mean(DWORD &processId, float &cpu_usage)
{
    // 1. 参数校验
    if (processId == 0)
    {
        qCritical("%s: Invalid process ID", __FUNCTION__);
        return false;
    }

    // 2. 使用RAII管理进程句柄
    HandleGuard hProcess(OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId));

    if (!hProcess)
    {
        qCritical("%s: OpenProcess failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }

    // 3. 获取进程时间信息
    FILETIME creationTime, exitTime, kernelTime, userTime, now;
    GetSystemTimeAsFileTime(&now);

    if (!GetProcessTimes(hProcess, &creationTime, &exitTime, &kernelTime, &userTime))
    {
        qCritical("%s: GetProcessTimes failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }

    // 4. 转换时间格式
    auto convertFileTime = [](const FILETIME *ft) {
        ULARGE_INTEGER uli;
        uli.LowPart = ft->dwLowDateTime;
        uli.HighPart = ft->dwHighDateTime;
        return uli.QuadPart;
    };

    const int64_t systemTime = convertFileTime(&kernelTime) + convertFileTime(&userTime);
    const int64_t currentTime = convertFileTime(&now);

    // 5. 初始化或更新进程时间数据
    auto &timeData = processTimeMap[processId];
    const auto nowClock = std::chrono::steady_clock::now();

    // 6. 首次调用处理
    if (timeData.last_system_time == 0 || timeData.last_time == 0)
    {
        timeData.last_system_time = systemTime;
        timeData.last_time = currentTime;
        timeData.last_update = nowClock;
        return false;
    }

    // 7. 计算时间差和CPU使用率
    const int64_t systemDelta = systemTime - timeData.last_system_time;
    const int64_t timeDelta = currentTime - timeData.last_time;
    const auto timePassed = std::chrono::duration_cast<std::chrono::milliseconds>(
                                nowClock - timeData.last_update)
                                .count();

    // 8. 更新最后记录的时间
    timeData.last_system_time = systemTime;
    timeData.last_time = currentTime;
    timeData.last_update = nowClock;

    // 9. 计算CPU使用率（考虑多核处理器）
    if (timeDelta > 0 && timePassed > 0)
    {
        SYSTEM_INFO sysInfo;
        GetSystemInfo(&sysInfo);
        const int cpuCount = sysInfo.dwNumberOfProcessors;

        // 转换为百分比并考虑多核
        cpu_usage = (systemDelta * 100.0f) / (timeDelta * cpuCount);
        return true;
    }
    return false;
}

bool ProgressManage::get_memory_usage(DWORD &processId, uint64_t &mem, uint64_t &vmem)
{
    // 1. 参数校验
    if (processId == 0)
    {
        qCritical("%s: Invalid process ID", __FUNCTION__);
        return false;
    }

    // 2. 使用RAII管理进程句柄
    HandleGuard hProcess(OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, processId));

    if (!hProcess)
    {
        qCritical("%s: OpenProcess failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }

    // 3. 获取内存信息
    PROCESS_MEMORY_COUNTERS_EX pmc;
    if (!GetProcessMemoryInfo(hProcess, reinterpret_cast<PROCESS_MEMORY_COUNTERS *>(&pmc), sizeof(pmc)))
    {
        qCritical("%s: GetProcessMemoryInfo failed (Error: %lu)",
                  __FUNCTION__, GetLastError());
        return false;
    }

    // 4. 返回内存数据
    mem = pmc.WorkingSetSize; // 物理内存使用量(工作集)
    vmem = pmc.PrivateUsage;  // 虚拟内存使用量(推荐替代PagefileUsage)
    return true;
}

bool ProgressManage::get_io_bytes(DWORD &processId, uint64_t &read_bytes, uint64_t &write_bytes)
{
    // 1. 参数校验
    if (processId == 0)
    {
        qCritical("%s: Invalid process ID", __FUNCTION__);
        return false;
    }

    // 2. 使用RAII管理进程句柄
    HandleGuard hProcess(
        OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ,
                    FALSE,
                    processId));

    if (!hProcess)
    {
        qCritical("%s: OpenProcess failed for PID %lu (Error: %lu)",
                  __FUNCTION__, processId, GetLastError());
        return false;
    }

    // 3. 获取IO计数器
    IO_COUNTERS io_counters;
    if (!GetProcessIoCounters(hProcess, &io_counters))
    {
        qCritical("%s: GetProcessIoCounters failed for PID %lu (Error: %lu)",
                  __FUNCTION__, processId, GetLastError());
        return false;
    }

    // 4. 返回IO数据
    read_bytes = io_counters.ReadTransferCount;
    write_bytes = io_counters.WriteTransferCount;
    return true;
}

bool ProgressManage::ServerRunWndProcess(LPWSTR lpExePath)
{
    // 1. 使用RAII管理令牌和句柄
    HANDLE hToken = NULL;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &hToken))
    {
        qCritical("%s: OpenProcessToken failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }
    HandleGuard tokenGuard(hToken);

    // 2. 复制令牌
    HANDLE hTokenDup = NULL;
    if (!DuplicateTokenEx(hToken,
                          TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, // 必要权限[9,10](@ref)
                          NULL,
                          SecurityIdentification,
                          TokenPrimary,
                          &hTokenDup))
    {
        qCritical("%s: DuplicateTokenEx failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }
    HandleGuard dupTokenGuard(hTokenDup);

    // 3. 设置会话ID
    DWORD dwSessionId = WTSGetActiveConsoleSessionId();
    if (!SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD)))
    {
        qCritical("%s: SetTokenInformation failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }

    // 4. 准备启动信息
    STARTUPINFO si = {sizeof(STARTUPINFO)};
    si.lpDesktop = const_cast<LPWSTR>(L"winsta0\\default");
    si.wShowWindow = SW_SHOW;
    si.dwFlags = STARTF_USESHOWWINDOW;

    // 5. 创建环境块
    LPVOID pEnv = NULL;
    if (!CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE) || !pEnv)
    {
        qCritical("%s: CreateEnvironmentBlock failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }
    LPVOIDeGuard pEnvGuard(pEnv);

    // 6. 提取工作目录
    std::wstring exePath(lpExePath);
    size_t lastSlash = exePath.find_last_of(L"\\/");
    std::wstring workDir = (lastSlash != std::wstring::npos) ? exePath.substr(0, lastSlash) : L"";

    // 7. 创建进程
    PROCESS_INFORMATION pi = {0};
    if (!CreateProcessAsUserW( // 使用宽字符版本
            hTokenDup,
            lpExePath,
            NULL,  // 命令行参数
            NULL,  // 进程安全属性
            NULL,  // 线程安全属性
            FALSE, // 不继承句柄
            NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
            pEnv,
            workDir.empty() ? NULL : workDir.c_str(),
            &si,
            &pi))
    {
        qCritical("%s: CreateProcessAsUser failed (Error: %lu)",
                  __FUNCTION__, GetLastError());
        return false;
    }

    // 8. 关闭进程/线程句柄
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return true;
}

bool ProgressManage::serverCreateProcessAsAdmin(string &path)
{
    // 1. 获取winlogon进程ID
    DWORD dwWinlogon = 0;
    if (!getWinlogonProcessId(dwWinlogon) || dwWinlogon == 0)
    {
        qCritical("%s: Failed to get winlogon PID", __FUNCTION__);
        return false;
    }

    // 2. 使用RAII管理句柄
    HandleGuard hProcess(
        OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwWinlogon));
    if (!hProcess)
    {
        qCritical("%s: OpenProcess failed for winlogon (PID: %lu, Error: %lu)", __FUNCTION__, dwWinlogon, GetLastError());
        return false;
    }

    // 3. 获取进程令牌
    HANDLE hToken = NULL;
    if (!OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &hToken))
    {
        qCritical("%s: OpenProcessToken failed (Error: %lu)", __FUNCTION__, GetLastError());
        return false;
    }
    HandleGuard tokenGuard(hToken);

    // 4. 复制令牌
    HANDLE hTokenDup = NULL;
    if (!DuplicateTokenEx(hToken,
                          TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
                          NULL,
                          SecurityIdentification,
                          TokenPrimary,
                          &hTokenDup))
    {
        qCritical("%s: DuplicateTokenEx failed (Error: %lu)",
                  __FUNCTION__, GetLastError());
        return false;
    }
    HandleGuard dupTokenGuard(hTokenDup);

    // 5. 准备启动信息
    STARTUPINFOW si = {sizeof(STARTUPINFOW)};
    si.lpDesktop = const_cast<LPWSTR>(L"winsta0\\default");
    si.wShowWindow = SW_SHOW;
    si.dwFlags = STARTF_USESHOWWINDOW;

    // 6. 创建环境块
    LPVOID pEnv = NULL;
    if (!CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE) || !pEnv)
    {
        qCritical("%s: CreateEnvironmentBlock failed (Error: %lu)",
                  __FUNCTION__, GetLastError());
        return false;
    }
    LPVOIDeGuard pEnvGuard(pEnv);

    // 7. 提取工作目录
    std::wstring wpath = string_to_wstring(path);
    std::wstring workDir;
    size_t lastSlash = wpath.find_last_of(L"\\/");
    if (lastSlash != std::wstring::npos)
    {
        workDir = wpath.substr(0, lastSlash);
    }

    // 8. 创建进程
    PROCESS_INFORMATION pi = {0};
    if (!CreateProcessAsUserW(
            hTokenDup,
            wpath.c_str(),
            NULL,  // 命令行参数
            NULL,  // 进程安全属性
            NULL,  // 线程安全属性
            FALSE, // 不继承句柄
            NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
            pEnv,
            workDir.empty() ? NULL : workDir.c_str(),
            &si,
            &pi))
    {
        qCritical("%s: CreateProcessAsUser failed (Error: %lu)",
                  __FUNCTION__, GetLastError());
        return false;
    }

    // 9. 关闭进程/线程句柄
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return true;
}

bool ProgressManage::serverCreateProcessAsAdmin2(string &path)
{
    int index = path.find_last_of("/");
    string filedir = path.substr(0, index);

    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    BOOL bResult = FALSE;
    DWORD consoleSessionId, winlogonSessionId, winlogonPid;
    HANDLE hUserToken = INVALID_HANDLE_VALUE, hUserTokenDup = INVALID_HANDLE_VALUE,
           hPToken = INVALID_HANDLE_VALUE, hProcess = INVALID_HANDLE_VALUE;
    DWORD dwCreationFlags;

    int errorcode; //whl2023-10-18
    LPVOID pEnv = NULL;

    // 将客户端登录到本地计算机
    consoleSessionId = WTSGetActiveConsoleSessionId();

    //添加Sessionid用原始会话的sessionId
    {
        //==============================
        //    PWTS_SESSION_INFO psi;
        //    DWORD dwCount;

        //    qDebug() << QString("WTSGetActiveConsoleSessionId:%1").arg(hid);
        //    printf("WTSGetActiveConsoleSessionId: %d \n", hid);
        //    BOOL bRet = ;

        //    if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &psi, &dwCount)){
        //        std::wstring strName;
        //        for (unsigned int i = 0; i < dwCount; i ++)
        //        {
        //            if( wstring_to_string(psi[i].pWinStationName) != "Console"){
        //                consoleSessionId = psi[i].SessionId;
        //                qDebug() << "consoleSessionId:" << wstring_to_string(psi[i].pWinStationName).c_str() << psi[i].SessionId;
        //                break;
        //            }
        //            qDebug()<< psi[i].SessionId << "pWinStationName: "<<QString::fromStdWString(psi[i].pWinStationName);
        //            qDebug() << "SessionId:"<< psi[i].SessionId;
        //            qDebug() << "State:"<< psi[i].State;

        //            consoleSessionId = psi[i].SessionId;
        //            PVOID pstr = NULL;
        //            DWORD dwLen = 0;
        //            WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, consoleSessionId, WTS_INFO_CLASS::WTSUserName, (LPWSTR*)&pstr, &dwLen);

        //            std::wstring strUserName = (PWCHAR)pstr;
        //            qDebug() << "strUserName:  "<<QString::fromStdWString(strUserName);
        //printf("strUserName:%s \n", strUserName.c_str());

        //        }
        //        WTSFreeMemory(psi);
        //    }
    }
    //===============================
    // Find the winlogon process
    PROCESSENTRY32 procEntry;

    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnap == INVALID_HANDLE_VALUE)
    {
        return false;
    }

    procEntry.dwSize = sizeof(PROCESSENTRY32);

    if (!Process32First(hSnap, &procEntry))
    {
        return false;
    }

    bool isFrist = true;
    do
    {
        if (_wcsicmp(procEntry.szExeFile, L"winlogon.exe") == 0)
        {
            DWORD processIdToSessionId = 0;
            ProcessIdToSessionId(procEntry.th32ProcessID, &processIdToSessionId);
            if (isFrist && processIdToSessionId == consoleSessionId)
            {
                qDebug() << "是第一次，且属于控制台的winlogon";
                winlogonPid = procEntry.th32ProcessID;
                winlogonSessionId = consoleSessionId;
                isFrist = false;
            }
            else
            {
                qDebug() << "是第一次第一次，不是控制台的winlogon";
                winlogonPid = procEntry.th32ProcessID;
                winlogonSessionId = processIdToSessionId;
                isFrist = false;
            }
        }
    } while (Process32Next(hSnap, &procEntry));

    //    if(!WTSQueryUserToken(consoleSessionId,&hUserToken)){
    //        qCritical() << "WTSQueryUserToken error";
    //    }
    //    if(!WTSQueryUserToken(consoleSessionId,&hUserToken)){
    //        qCritical() << "WTSQueryUserToken error";
    //    }
    dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    wchar_t desktopName[] = TEXT("winsta0\\default");
    si.lpDesktop = (wchar_t *)desktopName; ///加入窗口站
    ZeroMemory(&pi, sizeof(pi));
    TOKEN_PRIVILEGES tp;
    LUID luid;

    hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, winlogonPid);

    if (!::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, &hPToken))
    {
        errorcode = GetLastError();
        qCritical() << "Process token open Error:" << errorcode;
        goto ToFree;
    }

    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
    {
        errorcode = GetLastError();
        qCritical() << "Lookup Privilege value Error:" << errorcode;
        goto ToFree;
    }
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hUserTokenDup))
    {
        errorcode = GetLastError();
        qCritical() << "Adjust Privilege value Error:" << errorcode;
        goto ToFree;
    }

    // 调整Token权限
    //    SetTokenInformation(hUserTokenDup,TokenSessionId,(void*)consoleSessionId,sizeof(DWORD));
    SetTokenInformation(hUserTokenDup, TokenSessionId, (void *)consoleSessionId, sizeof(DWORD));

    if (!AdjustTokenPrivileges(hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
                               (PTOKEN_PRIVILEGES)NULL, NULL))
    {
        errorcode = GetLastError();
        qCritical() << "Adjust Privilege value Error:";
        goto ToFree;
    }
    //创建进程环境快
    if (!CreateEnvironmentBlock(&pEnv, hUserTokenDup, TRUE))
    {
        errorcode = GetLastError();
        qCritical() << "CreateEnvironmentBlock error";
        goto ToFree;
    }
    else
    {
        dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
    }
    // 在客户端的登录会话中启动进程
    if (CreateProcessAsUser(
            hUserTokenDup, // client's access token
            //_T("cmd.exe"),        // file to execute
            //NULL,                 // command line
            NULL,                                          // file to execute
            (wchar_t *)string_to_wstring(path).c_str(),    // command line
            NULL,                                          // pointer to process SECURITY_ATTRIBUTES
            NULL,                                          // pointer to thread SECURITY_ATTRIBUTES
            FALSE,                                         // handles are not inheritable
            dwCreationFlags,                               // creation flags
            pEnv,                                          // pointer to new environment block
            (wchar_t *)string_to_wstring(filedir).c_str(), // name of current directory
            &si,                                           // pointer to STARTUPINFO structure
            &pi                                            // receives information about new process
            ))
    {
        bResult = true;
    }
    else
    {
        qCritical() << __FUNCTION__ << "CreateProcessAsUser error";
        errorcode = GetLastError();
    }
    // Perform All the Close Handles tasks
ToFree:
{
    if (hProcess != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hProcess);
    }
    if (hUserToken != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hUserToken);
    }
    if (hUserTokenDup != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hUserTokenDup);
    }
    if (hPToken != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hPToken);
    }
}
    return bResult;
}

bool ProgressManage::appCreateProcessAsAdmin(string &path)
{
    // 初始化 STARTUPINFO 结构体，并设置其大小。
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);

    // 设置新进程的窗口站和桌面。"winsta0\default" 是交互式用户的默认窗口站。
    wchar_t desktopName[] = TEXT("winsta0\\default");
    si.lpDesktop = (wchar_t *)desktopName;

    // 打开当前进程句柄以获取访问令牌。
    HANDLE hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, GetCurrentProcessId());
    if (hProcess == NULL)
    {
        qCritical() << __FUNCTION__ << "OpenProcess error";
        return false; // 如果无法打开进程，则返回失败。
    }

    // 获取当前进程的访问令牌。
    HANDLE hToken;
    BOOL bResult = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, &hToken);
    CloseHandle(hProcess); // 关闭进程句柄，不再需要它。
    if (FALSE == bResult)
    {
        qCritical() << __FUNCTION__ << "OpenProcessToken error";
        return false; // 如果无法打开访问令牌，则返回失败。
    }

    // 创建一个新的主访问令牌副本，用于创建新进程。
    HANDLE hTokenDup = NULL;
    bool bRet = DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
    if (!bRet || hTokenDup == NULL)
    {
        qCritical() << __FUNCTION__ << "DuplicateTokenEx error";
        CloseHandle(hToken); // 清理资源。
        return false;        // 如果复制令牌失败，则返回失败。
    }

    // 创建一个环境块，为新进程提供环境变量。
    LPVOID pEnv = NULL;
    bRet = CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE);
    if (!bRet)
    {
        qCritical() << __FUNCTION__ << "CreateEnvironmentBlock error";
        CloseHandle(hTokenDup);
        CloseHandle(hToken); // 清理资源。
        return false;        // 如果创建环境块失败，则返回失败。
    }
    if (pEnv == NULL) // 检查环境块是否为空。
    {
        CloseHandle(hTokenDup);
        CloseHandle(hToken);
        return false;
    }

    // 初始化 PROCESS_INFORMATION 结构体。
    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

    // 设置创建标志，包括正常优先级、新的控制台和使用Unicode环境。
    DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;

    // 从路径中提取文件目录。
    int index = path.find_last_of("/");
    string filedir = path.substr(0, index);

    // 使用 CreateProcessAsUser 函数以管理员权限启动进程。
    if (!CreateProcessAsUser(hTokenDup, NULL, (wchar_t *)string_to_wstring(path).c_str(), NULL, NULL, FALSE, dwCreationFlags, pEnv, (wchar_t *)string_to_wstring(filedir).c_str(), &si, &pi))
    {
        qCritical() << __FUNCTION__ << "CreateProcessAsUser error";
        DWORD nRet = GetLastError(); // 获取错误代码。
        DestroyEnvironmentBlock(pEnv);
        CloseHandle(hTokenDup);
        CloseHandle(hToken); // 清理资源。
        return false;        // 如果创建进程失败，则返回失败。
    }

    // 清理环境块和访问令牌。
    DestroyEnvironmentBlock(pEnv);
    CloseHandle(hTokenDup);
    CloseHandle(hToken);

    // 成功创建进程后，返回 true。
    return true;
}

bool ProgressManage::startProcessByPath_S(string &path)
{
    DWORD progressId;
    //如果查不到该进程则启动
    if (getProcessIdByPath(path, progressId))
    {
        //qDebug() << QString("启动进程")<< progressId << QString::fromStdString(path);
        serverCreateProcessAsAdmin(path);
    }
    return true;
}

bool ProgressManage::startProcessByPath_A(string &path)
{
    DWORD progressId;
    //如果查不到该进程则启动
    if (!getProcessIdByPath(path, progressId))
    {
        //        qDebug() << QString("启动进程")<< progressId << QString::fromStdString(path);
        appCreateProcessAsAdmin(path);
    }
    return true;
}

bool ProgressManage::stopProcessByPath(string &path)
{
    DWORD progressId;
    //如果查不到该进程则启动
    if (getProcessIdByPath(path, progressId))
    {
        //qDebug() << QString("结束进程") << QString::fromStdString(path);
        killProcessById(progressId);
    }
    return true;
}

bool ProgressManage::getProcessToken(HANDLE *hToken)
{
    // 打开当前进程句柄。
    HANDLE hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, GetCurrentProcessId());
    if (hProcess == NULL)
    {
        qCritical() << __FUNCTION__ << "OpenProcess error";
        return false;
    }

    // 获取当前进程的访问令牌。
    //    TOKEN_ASSIGN_PRIMARY (0x0001):
    //    允许将访问令牌设置为新进程的主要令牌。这是创建新进程时必需的权限。
    //    TOKEN_DUPLICATE (0x0002):
    //    允许创建当前访问令牌的副本。这对于在不同的安全上下文中运行进程是必要的。
    //    TOKEN_IMPERSONATE (0x0004):
    //    允许模拟客户端的安全上下文。这通常用于服务器应用程序，以便它能够代表客户端执行操作。
    //    TOKEN_QUERY (0x0008):
    //    允许查询访问令牌的属性。例如，可以使用 GetTokenInformation 函数来获取关于令牌的信息，如用户身份、组成员资格和特权等。
    //    TOKEN_QUERY_SOURCE (0x0010):
    //    允许查询访问令牌的来源信息。这可以用来获取创建令牌的原始登录会话信息。
    //    TOKEN_ADJUST_PRIVILEGES (0x0020):
    //    允许启用或禁用访问令牌中的特权。这通常用于提升进程的权限以执行需要更高权限的操作。
    //    TOKEN_ADJUST_GROUPS (0x0040):
    //    允许调整访问令牌中的用户组成员资格。这可以用来添加或移除组成员资格，但通常不推荐这样做，因为这可能会影响系统安全性。
    //    TOKEN_ADJUST_DEFAULT (0x0080):
    //    允许调整访问令牌的默认 DACL（离散访问控制列表）。这可以用来更改与令牌关联的对象的默认权限。
    //    TOKEN_ADJUST_SESSIONID (0x0100):
    //    允许调整访问令牌的会话 ID。这个权限对于终端服务环境特别有用，在那里你可能需要改变进程所属的会话。
    if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, hToken))
    {
        qCritical() << __FUNCTION__ << "OpenProcessToken error";
        CloseHandle(hProcess);
        return false;
    }

    // 关闭不再需要的进程句柄。
    CloseHandle(hProcess);
    return true;
}
